package com.atguigu.gmall.activity.receiver;

import com.atguigu.gmall.activity.mapper.SeckillGoodsMapper;
import com.atguigu.gmall.activity.service.SeckillGoodsService;
import com.atguigu.gmall.common.constant.MqConst;
import com.atguigu.gmall.common.constant.RedisConst;
import com.atguigu.gmall.common.util.DateUtil;
import com.atguigu.gmall.model.activity.SeckillGoods;
import com.atguigu.gmall.model.activity.UserRecode;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.rabbitmq.client.Channel;
import lombok.SneakyThrows;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.rabbit.annotation.Exchange;
import org.springframework.amqp.rabbit.annotation.Queue;
import org.springframework.amqp.rabbit.annotation.QueueBinding;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;

import java.util.Date;
import java.util.List;

@Component
public class SeckillReceiver {

    @Autowired
    private SeckillGoodsMapper seckillGoodsMapper;

    @Autowired
    private RedisTemplate redisTemplate;

    @Autowired
    private SeckillGoodsService seckillGoodsService;

    @SneakyThrows
    @RabbitListener(bindings = @QueueBinding(
            value = @Queue(value = MqConst.QUEUE_TASK_1, durable = "true", autoDelete = "false"),
            exchange = @Exchange(value = MqConst.EXCHANGE_DIRECT_TASK),
            key = {MqConst.ROUTING_TASK_1}
    ))
    public void importDataToRedis(String msg, Message message, Channel channel) {
        // 查询秒杀商品： 当天时间{select date_format(start_time,'%Y-%m-%d') from seckill_goods}
        // 状态   status = 1 stock_count > 0;
        try {
            System.out.println(msg);
            QueryWrapper<SeckillGoods> seckillGoodsQueryWrapper = new QueryWrapper<>();
            seckillGoodsQueryWrapper.eq("status", "1");
            seckillGoodsQueryWrapper.gt("stock_count", 0);
            seckillGoodsQueryWrapper.eq("data_format(start_time,'%Y-%m-%d')", DateUtil.formatDate(new Date()));

            List<SeckillGoods> seckillGoodsList = seckillGoodsMapper.selectList(seckillGoodsQueryWrapper);
            //  获取到当前秒杀商品之后，循环遍历到缓存中.
            if (!CollectionUtils.isEmpty(seckillGoodsList)) {
                for (SeckillGoods seckillGoods : seckillGoodsList) {
                    //  使用的数据类型 hash  hset key field value
                    String activityKey = RedisConst.SECKILL_GOODS;
                    //判断商品是否在redis中 如果是就不需要放入
                    Boolean result = redisTemplate.opsForHash().hasKey(activityKey, seckillGoods.getSkuId().toString());
                    //有这个商品
                    if (result) {
                        //  break;//    结束整个循环    continue; 结束当前本次循环  return 方法都停了！
                        continue;
                    }
                    this.redisTemplate.opsForHash().put(activityKey, seckillGoods.getSkuId().toString(), seckillGoods);
                    for (Integer i = 0; i < seckillGoods.getStockCount(); i++) {
                        this.redisTemplate.opsForList().leftPush(RedisConst.SECKILL_STOCK_PREFIX + seckillGoods.getSkuId(), seckillGoods.getSkuId().toString());
                    }
                    //  使用redis 订阅、发布 同步状态位！ 初始化状态位都是 skuId:1
                    this.redisTemplate.convertAndSend("seckillpush", seckillGoods.getSkuId() + ":1");
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        channel.basicAck(message.getMessageProperties().getDeliveryTag(), false);
    }

    //  监听用户与商品的消息！
    @SneakyThrows
    @RabbitListener(bindings = @QueueBinding(
            value = @Queue(value = MqConst.QUEUE_SECKILL_USER, durable = "true", autoDelete = "false"),
            exchange = @Exchange(value = MqConst.EXCHANGE_DIRECT_SECKILL_USER),
            key = {MqConst.ROUTING_SECKILL_USER}))
    public void seckillOrder(UserRecode userRecode, Message message, Channel channel) {
        //判断
        try {
            if (userRecode!=null) {
                seckillGoodsService.seckillOrder(userRecode.getSkuId(),userRecode.getUserId());
            }
        } catch (Exception e) {
            e.printStackTrace();
        }

        channel.basicAck(message.getMessageProperties().getDeliveryTag(),false);
    }
}
